/*
 * Copyright (c) 2021 iSoftStone Information Technology (Group) co., ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "iss_led.h"
#include "iss_c_link.h"
#include "iss_view.h"

#define LED_DUTY 40000
#define LED_FREQ 40000
#define LED_THREAD_DELAY_TIME (1000 * 1000)

LedState g_currentLedState = MIN_LED_STATE;

void ColorfulLampControl(void)
{
    g_currentLedState++;
    switch (g_currentLedState) {
        case MIN_LED_STATE:
            break;
        case RED_LIGHT_ON:
            IssTurnOnLedByGPIO(HI_GPIO_IDX_10);
            usleep(LED_THREAD_DELAY_TIME);
            break;
        case RED_LIGHT_OFF:
            IssTurnOffLedByGPIO(HI_GPIO_IDX_10);
            break;
        case YELLOW_LIGHT_ON:
            IssTurnOnLedByGPIO(HI_GPIO_IDX_12);
            usleep(LED_THREAD_DELAY_TIME);
            break;
        case YELLOW_LIGHT_OFF:
            IssTurnOffLedByGPIO(HI_GPIO_IDX_12);
            break;
        case GREEN_LIGHT_ON:
            IssTurnOnLedByGPIO(HI_GPIO_IDX_11);
            usleep(LED_THREAD_DELAY_TIME);
            break;
        case GREEN_LIGHT_OFF:
            IssTurnOffLedByGPIO(HI_GPIO_IDX_11);
            g_currentLedState = MIN_LED_STATE;
            break;
        case MAX_LED_STATE:
            g_currentLedState = MIN_LED_STATE;
            break;
        default:
            printf("fatal error: case default option \r\n");
            break;
    }
}

// Initialize GPIO pin number direction and function
uint32_t InitLedGpioDirAndFunc(hi_io_name ioName, hi_gpio_idx gpioIdx)
{
    uint32_t state;
    state = hi_io_set_func(ioName, HI_IO_FUNC_GPIO_0_GPIO);
    RUNTIME_ERR_RET_FAIL(state != HI_ERR_SUCCESS, "set func failure,state=0x%x, ioName=%d", state, ioName);

    state = IoTGpioSetDir(gpioIdx, IOT_GPIO_DIR_OUT);
    RUNTIME_ERR_RET_FAIL(state != HI_ERR_SUCCESS, "set dir failure,state=0x%x, gpioIdx=%d", state, gpioIdx);

    return state;
}

// The pin and direction of the pin required to initialize the LED
uint32_t IssInitLedByGpio(void)
{
    uint32_t state;
    state = InitLedGpioDirAndFunc(HI_IO_NAME_GPIO_10, HI_GPIO_IDX_10);
    RUNTIME_ERR_RET_FAIL(state != HI_ERR_SUCCESS, "init GPIO_IDX_10 dir and func failure");
    state = InitLedGpioDirAndFunc(HI_IO_NAME_GPIO_11, HI_GPIO_IDX_11);
    RUNTIME_ERR_RET_FAIL(state != HI_ERR_SUCCESS, "init GPIO_IDX_11 dir and func failure");
    state = InitLedGpioDirAndFunc(HI_IO_NAME_GPIO_12, HI_GPIO_IDX_12);
    RUNTIME_ERR_RET_FAIL(state != HI_ERR_SUCCESS, "init GPIO_IDX_12 dir and func failure");
    return state;
}

uint32_t IssTurnOnLedByGPIO(hi_gpio_idx gpioIdx)
{
    uint32_t state = IoTGpioSetOutputVal(gpioIdx, HI_GPIO_VALUE1);
    RUNTIME_ERR_RET_FAIL(state != HI_ERR_SUCCESS, "set io value failure,state=0x%x,gpioIdx=%d", state, gpioIdx);
    return state;
}

uint32_t IssTurnOffLedByGPIO(hi_gpio_idx gpioIdx)
{
    uint32_t state = IoTGpioSetOutputVal(gpioIdx, HI_GPIO_VALUE0);
    RUNTIME_ERR_RET_FAIL(state != HI_ERR_SUCCESS, "set io value failure,state=0x%x,gpioIdx=%d", state, gpioIdx);
    return state;
}

// Turn on all LED lights
uint32_t IssTurnOnAllLedByGPIO(void)
{
    uint32_t state;
    state = IssTurnOnLedByGPIO(HI_GPIO_IDX_10);
    RUNTIME_ERR_RET_FAIL(state != HI_ERR_SUCCESS, "Turn on HI_GPIO_IDX_10 failure,state=0x%x", state);
    state = IssTurnOnLedByGPIO(HI_GPIO_IDX_11);
    RUNTIME_ERR_RET_FAIL(state != HI_ERR_SUCCESS, "Turn on HI_GPIO_IDX_11 failure,state=0x%x", state);
    state = IssTurnOnLedByGPIO(HI_GPIO_IDX_12);
    RUNTIME_ERR_RET_FAIL(state != HI_ERR_SUCCESS, "Turn on HI_GPIO_IDX_12 failure,state=0x%x", state);
    return state;
}

// Turn off all LED lights
uint32_t IssTurnOffAllLedByGPIO(void)
{
    uint32_t state;
    state = IssTurnOffLedByGPIO(HI_GPIO_IDX_10);
    RUNTIME_ERR_RET_FAIL(state != HI_ERR_SUCCESS, "Turn off HI_GPIO_IDX_10 failure,state=0x%x", state);
    state = IssTurnOffLedByGPIO(HI_GPIO_IDX_11);
    RUNTIME_ERR_RET_FAIL(state != HI_ERR_SUCCESS, "Turn on HI_GPIO_IDX_11 failure,state=0x%x", state);
    state = IssTurnOffLedByGPIO(HI_GPIO_IDX_12);
    RUNTIME_ERR_RET_FAIL(state != HI_ERR_SUCCESS, "Turn on HI_GPIO_IDX_12 failure,state=0x%x", state);
    return state;
}
// Turn off all LED lights
uint32_t IssTurnOffAllLedByPwm(void)
{
    // PWM is used to control the lamp off
    uint32_t state;
    state = IoTPwmStop(HI_PWM_PORT_PWM1);
    RUNTIME_ERR_RET_FAIL(state != HI_ERR_SUCCESS, "HI_PWM_PORT_PWM1 failure,state=0x%x", state);
    state = IoTPwmStop(HI_PWM_PORT_PWM2);
    RUNTIME_ERR_RET_FAIL(state != HI_ERR_SUCCESS, "HI_PWM_PORT_PWM2 failure,state=0x%x", state);
    state = IoTPwmStop(HI_PWM_PORT_PWM3);
    RUNTIME_ERR_RET_FAIL(state != HI_ERR_SUCCESS, "HI_PWM_PORT_PWM3 failure,state=0x%x", state);
    return state;
}
// Turn on all LED lights
uint32_t IssTurnOnAllLedByPwm(void)
{
    // PWM is used to control the light on
    uint32_t state;
    state = IssPwmOut(HI_PWM_PORT_PWM1, LED_DUTY, LED_FREQ);
    RUNTIME_ERR_RET_FAIL(state != HI_ERR_SUCCESS, "HI_PWM_PORT_PWM1 failure,state=0x%x", state);
    state = IssPwmOut(HI_PWM_PORT_PWM2, LED_DUTY, LED_FREQ);
    RUNTIME_ERR_RET_FAIL(state != HI_ERR_SUCCESS, "HI_PWM_PORT_PWM2 failure,state=0x%x", state);
    state = IssPwmOut(HI_PWM_PORT_PWM3, LED_DUTY, LED_FREQ);
    RUNTIME_ERR_RET_FAIL(state != HI_ERR_SUCCESS, "HI_PWM_PORT_PWM3 failure,state=0x%x", state);
    return state;
}

uint32_t IssPwmOut(hi_pwm_port pwmPort, uint16_t duty, uint32_t freq)
{
    uint32_t state = hi_pwm_start(pwmPort, duty, freq); /* duty: 750 freq:1500      scope:1~65535*/
    RUNTIME_ERR_RET_FAIL(state != HI_ERR_SUCCESS, "pwm start failure.state=0x%x", state);
    return state;
}

uint32_t IssInitLedByPwmPinFunc(hi_pwm_port pwmPort, hi_gpio_idx gpioIdx, hi_io_name ioName,
                                hi_io_func_gpio_10 gpioFunc)
{
    uint32_t state;
    state = hi_pwm_init(pwmPort);
    RUNTIME_ERR_RET_FAIL(state != HI_ERR_SUCCESS, "init pwm failure.state=0x%x", state);
    // Set the function of the specified pin as PWM output
    state = hi_io_set_func(ioName, gpioFunc);
    RUNTIME_ERR_RET_FAIL(state != HI_ERR_SUCCESS, "io set GPIO failure.state=0x%x", state);
    // Sets the direction of the pin to output
    state = IoTGpioSetDir(gpioIdx, HI_GPIO_DIR_OUT);
    RUNTIME_ERR_RET_FAIL(state != HI_ERR_SUCCESS, "io set dir  failure.state=0x%x", state);
    return state;
}

uint32_t IssInitLedByPwm(void)
{
    uint32_t state;
    state = IssInitLedByPwmPinFunc(HI_PWM_PORT_PWM1, HI_GPIO_IDX_10, HI_IO_NAME_GPIO_10, HI_IO_FUNC_GPIO_10_PWM1_OUT);
    RUNTIME_ERR_RET_FAIL(state != HI_ERR_SUCCESS, "IssInitLedByPwmPinFunc HI_PWM_PORT_PWM1 failure.state=0x%x", state);
    state = IssInitLedByPwmPinFunc(HI_PWM_PORT_PWM2, HI_GPIO_IDX_11, HI_IO_NAME_GPIO_11,
                                   HI_IO_FUNC_GPIO_11_PWM2_OUT);
    RUNTIME_ERR_RET_FAIL(state != HI_ERR_SUCCESS, "IssInitLedByPwmPinFunc HI_PWM_PORT_PWM2 failure.state=0x%x", state);
    state = IssInitLedByPwmPinFunc(HI_PWM_PORT_PWM3, HI_GPIO_IDX_12, HI_IO_NAME_GPIO_12,
                                   HI_IO_FUNC_GPIO_12_PWM3_OUT);
    RUNTIME_ERR_RET_FAIL(state != HI_ERR_SUCCESS, "IssInitLedByPwmPinFunc HI_PWM_PORT_PWM3 failure.state=0x%x", state);
    return state;
}
